package com.shanhesoft.java.modules.exam.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.shanhesoft.java.common.core.util.Result;
import com.shanhesoft.java.common.rancher.Rancher;
import com.shanhesoft.java.common.rancher.base.TypeCollection;
import com.shanhesoft.java.common.rancher.service.ContainerService;
import com.shanhesoft.java.common.rancher.service.HostService;
import com.shanhesoft.java.common.rancher.service.VolumeService;
import com.shanhesoft.java.common.rancher.type.Container;
import com.shanhesoft.java.common.rancher.type.Host;
import com.shanhesoft.java.common.rancher.type.Instance;
import com.shanhesoft.java.common.rancher.type.InstanceStop;
import com.shanhesoft.java.common.rancher.type.Volume;
import com.shanhesoft.java.common.ws.HoststatsWebSocketClient;
import com.shanhesoft.java.modules.exam.util.PropertiesUtils;
import com.shanhesoft.java.modules.exam.util.RancherUtils;
import com.shanhesoft.java.modules.sys.domain.dto.ContainerDTO;
import com.shanhesoft.java.modules.sys.domain.vo.ContainerVolumeVO;

import retrofit2.Response;

@Service
public class RancherService {
	
	private final Logger logger = LoggerFactory.getLogger(RancherService.class);

	private static Rancher rancher = RancherUtils.getInstance();
	private static Rancher rancher_v2 = RancherUtils.getInstanceV2();
	
	/**
	 * 获取所有主机列表
	 * @return
	 * @throws Exception
	 */
	public List<Host> listAllActive() throws Exception{
		HostService hostService = rancher_v2.type(HostService.class);
		Map<String, String> tmpFilters = new HashMap<String, String>();
		tmpFilters.put("state_eq", "active");
		Response<TypeCollection<Host>> execute = hostService.list(tmpFilters).execute();
		if(execute.isSuccess()) {
			List<Host> data = execute.body().getData();
			logger.info("获取active主机成功！dataSize:{}", data.size());
			return data;
			
		}
		return null;
	}
	
	/**
	 * 根据参数获取容器列表
	 * @param filters
	 * @return
	 * @throws Exception
	 */
	public List<Instance> listRunningInstances(String hostId) throws Exception{
		HostService hostService = rancher.type(HostService.class);
		Response<TypeCollection<Instance>> execute = hostService.listInstances(hostId).execute();
		if(execute.isSuccess()) {
			List<Instance> res = new ArrayList<Instance>();
			List<Instance> data = execute.body().getData();
			logger.info("获取容器成功！dataSize:{}", data.size());
			for (int i = 0; i < data.size(); i++) {
				Instance instance = data.get(i);
				String state = instance.getState();
				if("running".equalsIgnoreCase(state) || "starting".equalsIgnoreCase(state)) {
					res.add(instance);
				}
			}
			return res;
		}
		return null;
	}
	
	public Result listAllUserContainers(){
		ContainerService containerService = rancher.type(ContainerService.class);
		Map<String, Object> filters = new HashMap<String, Object>();
		filters.put("limit", 10000);
		try {
			Response<TypeCollection<Container>> execute = containerService.list(filters).execute();
			if(execute.isSuccess()) {
				List<Container> res = new ArrayList<Container>();
				List<Container> data = execute.body().getData();
				for (int i = 0; i < data.size(); i++) {
					Container container = data.get(i);
					String imageUuid = container.getImageUuid();
					if(!imageUuid.startsWith("docker:rancher") && !imageUuid.contains("sonatype/nexus3")
							 && !imageUuid.contains("novnc-proxy")) {
						logger.info("镜像名称："+imageUuid+",数组索引："+i+",列表长度："+data.size());
						res.add(container);
					}
				}
				return Result.buildOkData(res, "获取用户容器成功");
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("获取用户容器异常，异常信息："+e.getMessage());
		}
		return Result.buildFail("获取用户容器失败");
	}
	
	/**
	 * 根据参数获取容器列表
	 * @param filters
	 * @return
	 * @throws Exception
	 */
	public long getStartingInstancesMem(String hostId) throws Exception{
		HostService hostService = rancher.type(HostService.class);
		Response<TypeCollection<Instance>> execute = hostService.listInstances(hostId).execute();
		long mem = 0;
		if(execute.isSuccess()) {
			List<Instance> data = execute.body().getData();
			logger.info("获取容器成功！dataSize:{}", data.size());
			for (int i = 0; i < data.size(); i++) {
				Instance instance = data.get(i);
				String state = instance.getState();
				if("starting".equalsIgnoreCase(state)) {
					Long memory = instance.getMemory();
					if(memory != null) {
						mem += memory.longValue();
					}else {
						mem += 2147483648L;
					}
				}
			}
			return mem;
		}
		return mem;
	}
	
	/**
	 * 调度主机，获取资源最充足的主机信息或资源最不充足的主机信息
	 * @param memory 调度的容器内存
	 * @param isMostAbundant  是否是资源最充足调度，ture资源最充足调度，false资源最不充足调度
	 * @return
	 */
	public Result schedulingHost(Integer memory, boolean isMostAbundant) {
		List<Host> listAll = null;
		Map<String, Integer> notAlertHostContainerRunNum = new ConcurrentHashMap<String, Integer>();
		Map<String, Host> notAlertHosts = new ConcurrentHashMap<String, Host>();
		try {
			//获取所有状态为active的主机
			listAll = listAllActive();
			if(listAll == null || listAll.size() == 0) {
				logger.error("调度失败，没有主机！");
				return Result.buildFail("调度失败，没有主机！");
			}
			
			//计算每个主机预计最大能够创建的容器数量及内存剩余占比超出上限的值及所有主机运行容器数量/报警主机/非报警主机
			for (Host host : listAll) {
				String state = host.getState();
				Object novncHost = host.getLabels().get("novnc.proxy.host");
				logger.info("主机ip：{},主机状态：{}",host.getAgentIpAddress(), state);
				//如果不为active状态移除主机
				if(!"active".equalsIgnoreCase(state) || !ObjectUtils.isEmpty(novncHost)) {
					continue;
				}
				String id = host.getId();
//				Map<String, Object> info = host.getInfo();
//				Map<String, Integer> memoryInfo = (Map<String, Integer>) info.get("memoryInfo");
//				Integer memTotal = memoryInfo.get("memTotal");
				
				//获取正在启动的容器内存
				long startingInstancesMem = getStartingInstancesMem(id);
				
//				Integer memAvailable = memoryInfo.get("memAvailable");
//				Integer activeMem = memoryInfo.get("active");
				ConcurrentHashMap<String, Long> memoryInfo = HoststatsWebSocketClient.HOST_MEM_MAP.get(id);
				if(memoryInfo == null) {
					continue;
				}
				Long memTotal = memoryInfo.get("memTotal");
				Long usage = memoryInfo.get("usage");
				String memLimit = PropertiesUtils.getProperty("rancher.host.mem.limit");
				if(StringUtils.isEmpty(memLimit)) {
					logger.error("获取内存限制配置信息失败！");
					return Result.buildFail("获取内存限制配置信息失败！");
				}
				String ratioStr = PropertiesUtils.getProperty("rancher.container.user.mem.ratio");
				if(StringUtils.isEmpty(ratioStr)) {
					logger.error("获取用户容器内存使用率系数失败！");
					return Result.buildFail("获取用户容器内存使用率系数失败！");
				}
				double ratio = Double.valueOf(ratioStr).doubleValue();
				//计算当前主机内存剩余占比超出上限的值
				BigDecimal memLimitVal = new BigDecimal(usage).add(new BigDecimal(startingInstancesMem*ratio))
						.multiply(new BigDecimal(100))
						.divide(new BigDecimal(memTotal), 0, BigDecimal.ROUND_HALF_UP)
						.subtract(new BigDecimal(memLimit));
				int memLimitInt = memLimitVal.intValue();
				
				 
				//获取主机正在运行的容器
				int runContainerNum = 0;
				try {
					//running
					List<Instance> runningInstances = listRunningInstances(id);
					if(runningInstances == null) {
						logger.error("未能获取到主机正在运行容器信息！");
						return Result.buildFail("未能获取到主机正在运行容器信息！");
					}
					runContainerNum = runningInstances.size();
					
				} catch (Exception e) {
					logger.error("获取主机正在运行容器信息异常！");
					e.printStackTrace();
					return Result.buildFail("获取主机正在运行容器信息异常！"+e.getMessage());
				}
				
				logger.info("内存超出上限值百分比:{}，当前主机ID:{}，当前主机可运行最大内存:{}MB，当前主机已用内存:{}MB，正在启动容器所需内存:{}MB，当前主机主机容器运行数量:{}", 
						memLimitInt, id, memTotal/1024/1024, usage/1024/1024, startingInstancesMem/1024/1024, runContainerNum);
				//判断创建的容器是否满足资源要求
				if(memLimitInt < 0 && Long.valueOf(memory).longValue()*1024*1024*ratio < memTotal.longValue()-usage.longValue()) {
					//将非预警主机放入列表
					notAlertHosts.put(id, host);
					notAlertHostContainerRunNum.put(id, runContainerNum);
				}
			}
			//如果没有计算出最少容器的主机，则从预警主机中获取运行容器最少的主机
			if(notAlertHosts.isEmpty()) {
				logger.error("资源不足，不能创建新容器，请稍后重试！");
				return Result.buildFail("资源不足，不能创建新容器，请稍后重试！");
			}
			if(notAlertHostContainerRunNum.isEmpty()) {
				logger.error("资源不足，不能创建新容器，请稍后重试！");
				return Result.buildFail("资源不足，不能创建新容器，请稍后重试！");
			}
			Set<Entry<String,Integer>> entrySet = notAlertHostContainerRunNum.entrySet();
			//计算容器最少主机
			//如果找到资源最少的预警主机，判断预警主机中运行的容器数量是否超出可运行容器的最大值，小于最大运行容器数量返回预警主机
			Result<Host> schedulingHost = null;
			if(isMostAbundant) {
				schedulingHost = minContainerNumHost(entrySet, notAlertHosts);
				
			}else {
				schedulingHost = maxContainerNumHost(entrySet, notAlertHosts);
			}
			return schedulingHost;
		} catch (Exception e) {
			logger.error("获取主机列表异常！");
			e.printStackTrace();
			return Result.buildFail("获取主机列表异常：异常信息："+e.getMessage());
		}
	}

	/**
	 * 计算容器最少主机
	 * @param systemConNum
	 * @param entrySet
	 * @return
	 */
	private Result<Host> minContainerNumHost( Set<Entry<String, Integer>> entrySet, Map<String, Host> hosts) {
		int minNum = Integer.MAX_VALUE;
		String minHostId = "";
		Host schedulingHost = null;
		for (Entry<String, Integer> entry : entrySet) {
			String key = entry.getKey();
			Integer value = entry.getValue();
			if(minNum > value.intValue()) {
				minNum = value.intValue();
				minHostId = key;
				schedulingHost = hosts.get(key);
			}
		}
		//如果未找到资源最少的预警主机返回失败
		if(StringUtils.isEmpty(minHostId) || minNum == Integer.MAX_VALUE) {
			logger.error("资源不足，不能创建新容器，请稍后重试！");
			return Result.buildFailData(schedulingHost, "资源不足，不能创建新容器，请稍后重试！");
		}
		logger.info("调度成功！主机ID:{}", schedulingHost.getId());
		return Result.buildOkData(schedulingHost, "调度主机成功！");
	}
	
	/**
	 * 计算容器最多主机
	 * @param systemConNum
	 * @param entrySet
	 * @return
	 */
	private Result<Host> maxContainerNumHost( Set<Entry<String, Integer>> entrySet, Map<String, Host> hosts) {
		int maxNum = Integer.MIN_VALUE;
		String minHostId = "";
		Host schedulingHost = null;
		for (Entry<String, Integer> entry : entrySet) {
			String key = entry.getKey();
			Integer value = entry.getValue();
			if(maxNum < value.intValue()) {
				maxNum = value.intValue();
				minHostId = key;
				schedulingHost = hosts.get(key);
			}
		}
		//如果未找到资源最多的主机返回失败
		if(StringUtils.isEmpty(minHostId) || maxNum == Integer.MIN_VALUE) {
			logger.error("资源不足，不能创建新容器，请稍后重试！");
			return Result.buildFailData(schedulingHost, "资源不足，不能创建新容器，请稍后重试！");
		}
		logger.info("调度成功！主机ID:{}", schedulingHost.getId());
		return Result.buildOkData(schedulingHost, "调度主机成功！");
	}
	
	/**
	 * 删除容器并删除关联的卷
	 * @param containerId
	 * @return
	 */
	@SuppressWarnings("static-access")
	public Result deleteContainer(String containerId) {
		if(StringUtils.isEmpty(containerId)) {
			return Result.buildFail("参数containerId不能为空");
		}
		ContainerService containerService = rancher.type(ContainerService.class);
		VolumeService volumeService = rancher.type(VolumeService.class);
		Response<Container> execute = null;
		try {
			execute = containerService.get(containerId).execute();
			if(execute != null && execute.isSuccess()) {
				Container body = execute.body();
				if(body == null) {
					return Result.buildFail("容器不存在！");
				}
				String state = body.getState();
				if("removed".equalsIgnoreCase(state) || "purged".equalsIgnoreCase(state)) {
					return Result.buildFail("容器已经删除，请勿重复操作！");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("获取容器信息出错！错误信息："+e.getMessage());
		}
		try {
			execute = containerService.delete(containerId).execute();
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("删除容器出错！错误信息："+e.getMessage());
		}
		List<String> volumeIds = new ArrayList<String>();
		if(execute != null && execute.isSuccess()) {
			Container body = execute.body();
			String state = body.getState();
			while(!"removed".equalsIgnoreCase(state) && !"purged".equalsIgnoreCase(state)) {
				try {
					Thread.currentThread().sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				try {
					execute = containerService.get(containerId).execute();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.buildFail("获取容器信息出错！错误信息："+e.getMessage());
				}
				if(execute.isSuccess()) {
					body = execute.body();
					state = body.getState();
				}
			}
			//删除卷
			Map<String, Object> dataVolumeMounts = body.getDataVolumeMounts();
			Collection<Object> values = dataVolumeMounts.values();
			for (Object obj : values) {
				String volId = String.valueOf(obj);
				volumeIds.add(volId);
				try {
					volumeService.delete(volId).execute();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.buildFail("删除卷出错！错误信息："+e.getMessage());
				}
				try {
					Thread.currentThread().sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return Result.buildOkData("containerId:"+containerId+",volumeIds:"+String.join(",", volumeIds), "删除容器及卷成功！");
	}

	/**
	 *  创建容器
	 * @param dto
	 * @return
	 */
	@SuppressWarnings("static-access")
	public Result<Container> createContainer(ContainerDTO dto) {
		String name = dto.getName();
		//判断名称是否有效
		if(StringUtils.isEmpty(name)) {
			name = UUID.randomUUID().toString().replace("-", "");
		}
		//判断内存是否有效
		Integer memory = dto.getMemory();
		if(memory == null) {
			String mem = PropertiesUtils.getProperty("rancher.container.default.mem");
			if(StringUtils.isEmpty(mem)) {
				memory = 2048;
			}else {
				memory = Integer.valueOf(mem);
			}
		}else if(memory.intValue() < 512) {
			memory = memory.intValue()*1024;
		}
		//判断镜像是否有效
		String imageUuid = dto.getImageUuid();
		if(StringUtils.isEmpty(imageUuid)) {
			return Result.buildFail("镜像不能为空！");
		}
		if(!imageUuid.startsWith("docker:")) {
			imageUuid = "docker:"+imageUuid;
		}
		//判断挂载卷是否有效
		List<String> dataVolumes = dto.getDataVolumes();
		if(dataVolumes != null && dataVolumes.size() > 0) {
			for (String dataVolume : dataVolumes) {
				if(StringUtils.isEmpty(dataVolume)) {
					return Result.buildFail("挂载卷中有空值，请处理后重试！");
				}
				String[] split = dataVolume.split(":");
				if(split.length != 2) {
					return Result.buildFail("挂载信息格式不对，请处理后重试！格式：'fromPath:toContainerPath'");
				}
			}
		}
		//判断驱动是否有效
		String volumeDriver = dto.getVolumeDriver();
		if(dataVolumes != null && dataVolumes.size() > 0 && StringUtils.isEmpty(volumeDriver)) {
			volumeDriver = "rancher-nfs";
		}
		String description = dto.getDescription();
		//判断核心是否有效
//		Integer cpuShares = dto.getCpuShares();
//		if(cpuShares == null) {
//			String cpu = PropertiesUtils.getProperty("rancher.container.default.cpu");
//			if(StringUtils.isEmpty(cpu)) {
//				cpuShares = 8000;
//			}else {
//				cpuShares = Integer.valueOf(cpu);
//			}
//		}else if(cpuShares.intValue() > 128 || cpuShares.intValue() <= 0) {
//			return R.data(R.ERROR, "cpu上限超出限额!", null);
//		}else if(cpuShares.intValue() > 0 && cpuShares.intValue() <= 128) {
//			cpuShares = cpuShares.intValue()*8000;
//		}
		//获取调度主机
		String schedulingHostMsg = "";
		String hostId = null;
		int schedulingHostStatus = 0;
		String isMostAbundantStr = PropertiesUtils.getProperty("rancher.scheduling.host.isMostAbundant");
		boolean isMostAbundant = true;
		if(!StringUtils.isEmpty(isMostAbundantStr)) {
			isMostAbundant = Boolean.valueOf(isMostAbundantStr).booleanValue();
		}
		Result<Host> schedulingHost = schedulingHost(memory, isMostAbundant);
		if(schedulingHost != null) {
			Host data = schedulingHost.getData();
			int code = schedulingHost.getCode();
			if(code != 1) {
				return Result.buildFail(schedulingHost.getMessage());
			}
			schedulingHostStatus = code;
			hostId = data.getId();
			schedulingHostMsg = schedulingHost.getMessage();
		}else {
			return Result.buildFail("获取可运行容器主机出错");
		}
		//创建容器
		ContainerService containerService = rancher.type(ContainerService.class);
		Container container = new Container();
		container.setName(name);
		container.setPublishAllPorts(false);
		container.setStartOnCreate(true);//创建后启动
		container.setPrivileged(false);
		container.setStdinOpen(true);
		container.setTty(true);
		container.setReadOnly(false);
		container.setRequestedHostId(hostId);//指定运行的主机Id
		container.setMemory(memory.intValue()*1024*1024L);//内存上限
		container.setMemorySwap(null);
//		container.setCpuShares(cpuShares);//CPU上限，1个核心8000
		container.setNetworkMode("managed");
		container.setImageUuid(imageUuid);
		container.setDataVolumes(dataVolumes);
	    container.setVolumeDriver(volumeDriver);
	    container.setDescription(description);
//		List<String> ports = new ArrayList<String>();
//		container.setPorts(ports );
		try {
			Response<Container> execute = containerService.create(container).execute();
			if(execute.isSuccess()) {
				Container body = execute.body();
				String id = body.getId();
				String primaryIpAddress = body.getPrimaryIpAddress();
				while(primaryIpAddress == null || primaryIpAddress == "") {
					try {
						Thread.currentThread().sleep(500);
					} catch (Exception e) {
						e.printStackTrace();
					}
					Response<Container> response = containerService.get(id).execute();
					body = response.body();
					String transitioning = body.getTransitioning();
					if("error".equals(transitioning)) {
						String transitioningMessage = body.getTransitioningMessage();
						return Result.buildFail("rancher创建容器异常！异常信息："+transitioningMessage);
					}
					primaryIpAddress = body.getPrimaryIpAddress();
				}
				//设置容器运行时间
				Integer runTime = dto.getRunTime();
				setContainerStopTime(runTime, body.getId());
				return Result.buildOkData(body, "创建容器成功！"+schedulingHostMsg);
			}
			return Result.buildFailData(container, "创建容器失败！创建请求未成功执行！");
		} catch (Exception e) {
			e.printStackTrace();
			return Result.buildFail("创建容器异常，异常信息："+e.getMessage());
		}
	}

	@SuppressWarnings("static-access")
	public Result<Container> stopContainer(String containerId) {
		if(StringUtils.isEmpty(containerId)) {
			return Result.buildFail("参数containerId不能为空！");
		}
		ContainerService containerService = rancher.type(ContainerService.class);
		try {
			Response<Container> execute = containerService.get(containerId).execute();
			if(execute != null && execute.isSuccess()) {
				Container body = execute.body();
				if(body == null) {
					return Result.buildFailData(body, "容器不存在！");
				}
				String state = body.getState();
				if("stopped".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器已停止，请勿重复操作！");
				}
				if("error".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器出现异常！异常信息："+body.getTransitioningMessage());
				}
				if("purged".equalsIgnoreCase(state) || "removed".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器已被被删除！");
				}
				if("stopping".equalsIgnoreCase(state)) {
					while(!"stopped".equals(state)) {
						try {
							Thread.currentThread().sleep(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						Response<Container> response = containerService.get(containerId).execute();
						body = response.body();
						String transitioning = body.getTransitioning();
						if("error".equals(transitioning)) {
							String transitioningMessage = body.getTransitioningMessage();
							Result.buildFailData(body, "rancher停止容器异常！异常信息："+transitioningMessage);
						}
						state = body.getState();
					}
					return Result.buildOkData(body, "rancher停止容器成功！");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("获取容器详情异常！异常信息："+e.getMessage());
		}
		try {
			InstanceStop instanceStop = new InstanceStop();
			instanceStop.setRemove(false);
			instanceStop.setTimeout(10);
			Response<Instance> execute = containerService.stop(containerId, instanceStop).execute();
			Container container = null;
			if(execute.isSuccess()) {
				Instance body = execute.body();
				String state = body.getState();
				String transitioning = body.getTransitioning();
				while(!"stopped".equals(state)) {
					try {
						Thread.currentThread().sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					Response<Container> response = containerService.get(containerId).execute();
					container = response.body();
					transitioning = container.getTransitioning();
					if("error".equals(transitioning)) {
						String transitioningMessage = container.getTransitioningMessage();
						return Result.buildFailData(container, "rancher停止容器异常！异常信息："+transitioningMessage);
					}
					state = container.getState();
				}
				return Result.buildOkData(container, "rancher停止容器成功！");
			}
			return Result.buildFail("执行停止容器请求未成功！"+execute.message());
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("rancher停止容器异常！"+e.getMessage());
		}
	}

	/**
	 * 启动容器
	 * @param containerId
	 * @return
	 */
	@SuppressWarnings("static-access")
	public Result<Container> startContainer(String containerId, Integer runTime) {
		if(StringUtils.isEmpty(containerId)) {
			return Result.buildFail("参数containerId不能为空！");
		}
		ContainerService containerService = rancher.type(ContainerService.class);
		try {
			Response<Container> execute = containerService.get(containerId).execute();
			if(execute != null && execute.isSuccess()) {
				Container body = execute.body();
				if(body == null) {
					return Result.buildFailData(body, "容器不存在！");
				}
				String state = body.getState();
				if("running".equalsIgnoreCase(state)) {
					return Result.buildOkData(body, "容器已启动，请勿重复操作！");
				}
				if("error".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器出现异常！异常信息："+body.getTransitioningMessage());
				}
				if("stopping".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器正在被停止，请稍后再启动！");
				}
				if("purged".equalsIgnoreCase(state) || "removed".equalsIgnoreCase(state)) {
					return Result.buildFailData(body, "容器已被被删除，请重建容器！");
				}
				if("starting".equalsIgnoreCase(state)) {
					while(!"running".equals(state)) {
						try {
							Thread.currentThread().sleep(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						Response<Container> response = containerService.get(containerId).execute();
						body = response.body();
						String transitioning = body.getTransitioning();
						if("error".equals(transitioning)) {
							String transitioningMessage = body.getTransitioningMessage();
							return Result.buildFailData(body, "rancher启动容器异常！异常信息："+transitioningMessage);
						}
						state = body.getState();
					}
					//设置容器运行时间
					String id = body.getId();
					setContainerStopTime(runTime, id);
					return Result.buildOkData(body, "启动容器成功！");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail( "获取容器详情异常！异常信息："+e.getMessage());
		}
		//获取主机信息
		try {
			Response<Container> execute = containerService.get(containerId).execute();
			if(execute.isSuccess()) {
				Container container = execute.body();
				String hostId = container.getHostId();
				//判断主机资源是否够用
				Long memory = container.getMemory();
				long conMem = 0;
				if(memory == null) {
					conMem = 2048*1024*1024;
				}else {
					conMem = memory.longValue();
				}
				Result<Boolean> hostCanUsed = hostCanUsed(hostId, conMem);
				//资源够用则启动
				if(1 == hostCanUsed.getCode() && hostCanUsed.getData().booleanValue() == true) {
					Response<Instance> execute2 = containerService.start(containerId).execute();
					if(execute2.isSuccess()) {
						Instance instance = execute2.body();
						String state = instance.getState();
						String transitioning = instance.getTransitioning();
						while(!"running".equals(state)) {
							try {
								Thread.currentThread().sleep(500);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							Response<Container> response = containerService.get(containerId).execute();
							container = response.body();
							transitioning = container.getTransitioning();
							if("error".equals(transitioning)) {
								String transitioningMessage = container.getTransitioningMessage();
								return Result.buildFailData(container, "rancher启动容器异常！异常信息："+transitioningMessage);
							}
							state = container.getState();
						}
						//设置容器运行时间
						setContainerStopTime(runTime, container.getId());
						return Result.buildOkData(container, "启动容器成功！");
					}
					return Result.buildFail("启动容器容器错误，请求未执行成功");
				}
				//资源不够用返回提示信息
				return Result.buildFailData(container, hostCanUsed.getMessage());
			}
			return Result.buildFail("获取容器详情错误，请求未执行成功");
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("获取容器详情异常，异常信息："+e.getMessage());
		}
	}

	/**
	 * 设置容器停止时间
	 * @param runTime
	 * @param id
	 */
	private void setContainerStopTime(Integer runTime, String id) {
//		List<ContainerRunTime> list = containerRunTimeService.findByContainerId(id);
//		ContainerRunTime containerRunTime = null;
//		if(list == null || list.size() == 0) {
//			containerRunTime = new ContainerRunTime();
//		}else {
//			containerRunTime = list.get(0);
//			
//		}
//		containerRunTime.setContainerId(id);
//		Long startTime = System.currentTimeMillis();
//		containerRunTime.setStartTime(startTime);
//		if(runTime == null || runTime.intValue() <= 0) {
//			runTime = 45;
//		}
//		Long endTime = startTime+runTime*60*1000;
//		containerRunTime.setEndTime(endTime);
//		containerRunTimeService.save(containerRunTime);
	}
	
	private Result<Boolean> hostCanUsed(String hostId, long memory){
		HostService hostService = rancher_v2.type(HostService.class);
		try {
			Response<Host> execute = hostService.get(hostId).execute();
			if(execute.isSuccess()) {
				Host host = execute.body();
				String state = host.getState();
				//如果不为active状态移除主机
				if(!"active".equalsIgnoreCase(state)) {
					return Result.buildFailData(false, "主机状态异常，主机不可用！");
				}
				String id = host.getId();
//				Map<String, Object> info = host.getInfo();
//				Map<String, Integer> memoryInfo = (Map<String, Integer>) info.get("memoryInfo");
//				Integer memTotal = memoryInfo.get("memTotal");
				
				//获取正在启动的容器内存
				long startingInstancesMem = getStartingInstancesMem(id);
				
//				Integer memAvailable = memoryInfo.get("memAvailable");
//				Integer activeMem = memoryInfo.get("active");
				ConcurrentHashMap<String, Long> memoryInfo = HoststatsWebSocketClient.HOST_MEM_MAP.get(id);
				if(memoryInfo == null) {
					logger.error("获取主机实时内存信息失败！主机id:{}", id);
					return  Result.buildFailData(false, "获取主机实时内存信息失败！主机id:"+id);
				}
				Long memTotal = memoryInfo.get("memTotal");
				Long usage = memoryInfo.get("usage");
				String memLimit = PropertiesUtils.getProperty("rancher.host.mem.limit");
				if(StringUtils.isEmpty(memLimit)) {
					logger.error("获取内存限制配置信息失败！");
					return  Result.buildFailData(false, "获取内存限制配置信息失败！");
				}
				String ratioStr = PropertiesUtils.getProperty("rancher.container.user.mem.ratio");
				if(StringUtils.isEmpty(ratioStr)) {
					logger.error("获取用户容器内存使用率系数失败！");
					return  Result.buildFailData(false, "用户容器内存使用率系数失败！");
				}
				double ratio = Double.valueOf(ratioStr).doubleValue();
				//计算当前主机内存剩余占比超出上限的值
				BigDecimal memLimitVal = new BigDecimal(usage).add(new BigDecimal(startingInstancesMem/1024/1024*ratio))
						.multiply(new BigDecimal(100))
						.divide(new BigDecimal(memTotal), 0, BigDecimal.ROUND_HALF_UP)
						.subtract(new BigDecimal(memLimit));
				int memLimitInt = memLimitVal.intValue();
				
				 
				//获取主机正在运行的容器
				int runContainerNum = 0;
				try {
					//running
					List<Instance> runningInstances = listRunningInstances(id);
					if(runningInstances == null) {
						logger.error("未能获取到主机正在运行容器信息！");
						return  Result.buildFailData(false, "未能获取到主机正在运行容器信息！");
					}
					runContainerNum = runningInstances.size();
					
				} catch (Exception e) {
					logger.error("获取主机正在运行容器信息异常！");
					e.printStackTrace();
					return  Result.buildFailData(false, "获取主机正在运行容器信息异常！"+e.getMessage());
				}
				
				logger.info("内存超出上限值百分比:{}，当前主机ID:{}，当前主机可运行最大内存:{}MB，当前主机已用内存:{}MB，正在启动容器所需内存:{}MB，当前主机主机容器运行数量:{}", 
						memLimitInt, id, memTotal/1024/1024, usage/1024/1024, startingInstancesMem/1024/1024, runContainerNum);
				//判断创建的容器是否满足资源要求
				if(memLimitInt < 0 && memory*ratio < memTotal.longValue()-usage.longValue()) {
					return Result.buildOkData(true, "可以打开容器！");
				}else {
					return  Result.buildFailData(false, "资源不足，不能打开容器，请稍后重试！");
				}
			}
			return  Result.buildFailData(false, "获取主机详情异常，请求未执行成功");
		} catch (Exception e) {
			e.printStackTrace();
			return  Result.buildFailData(false, "获取主机详情异常，异常信息："+e.getMessage());
		}
	}
	
	/**
	 * 删除所有容器及存储卷
	 */
	public void deleteContainers() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				ContainerService containerService = rancher.type(ContainerService.class);
				Map<String, Object> filters = new HashMap<String, Object>();
				filters.put("limit", 10000);
				try {
					Response<TypeCollection<Container>> execute = containerService.list(filters).execute();
					if(execute.isSuccess()) {
						List<Container> data = execute.body().getData();
						for (Container container : data) {
							String name = container.getName();
							if(!StringUtils.isEmpty(name) && name.endsWith("retain")) {
								continue;
							}
							String imageUuid = container.getImageUuid();
							if(!imageUuid.startsWith("docker:rancher") && !imageUuid.contains("sonatype/nexus3")
									&& !imageUuid.contains("novnc-proxy")) {
								String id = container.getId();
								deleteContainer(id);
							}
						}
					}
					filters.put("state", "detached");
					deleteVolumes(filters);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	@SuppressWarnings("static-access")
	private void deleteVolumes(Map<String, Object> filters) throws IOException {
		VolumeService volumeService = rancher.type(VolumeService.class);
		Response<TypeCollection<Volume>> execute2 = volumeService.list(filters).execute();
		if(execute2.isSuccess()) {
			List<Volume> data = execute2.body().getData();
			for (Volume volume : data) {
				try {
					volumeService.delete(volume.getId()).execute();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					Thread.currentThread().sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public Result<List<ContainerVolumeVO>> listConatinersVolumes(){
		List<ContainerVolumeVO> dataList = new ArrayList<ContainerVolumeVO>();
		ContainerService containerService = rancher.type(ContainerService.class);
		Map<String, Object> filters = new HashMap<String, Object>();
		filters.put("limit", 10000);
		try {
			Response<TypeCollection<Container>> execute = containerService.list(filters).execute();
			if(execute.isSuccess()) {
				List<Container> data = execute.body().getData();
				for (Container container : data) {
					String imageUuid = container.getImageUuid();
					if(!imageUuid.startsWith("docker:rancher") && !imageUuid.contains("sonatype/nexus3")
							&& !imageUuid.contains("novnc-proxy")) {
						ContainerVolumeVO vo = new ContainerVolumeVO();
						String id = container.getId();
						vo.setContainerId(id);
						String name = container.getName();
						vo.setContainerName(name);
						List<String> dataVolumes = container.getDataVolumes();
						List<Map<String, String>> volumes = new ArrayList<Map<String,String>>();
						if(dataVolumes != null) {
							Map<String, Object> dataVolumeMounts = container.getDataVolumeMounts();
							for (String vol : dataVolumes) {
								Map<String, String> m = new HashMap<String, String>();
								String volumeName = vol.split(":")[0];
								String volumeContainerPath = vol.split(":")[1];
								String volumeId = (String) dataVolumeMounts.get(volumeContainerPath);
								m.put("volumeId", volumeId);
								m.put("volumeName", volumeName);
								volumes.add(m);
							}
						}
						vo.setVolumes(volumes);
						dataList.add(vo);
					}
				}
			}
			filters.put("state", "detached");
			VolumeService volumeService = rancher.type(VolumeService.class);
			Response<TypeCollection<Volume>> execute2 = volumeService.list(filters).execute();
			ContainerVolumeVO vo = new ContainerVolumeVO();
			if(execute2.isSuccess()) {
				List<Volume> data = execute2.body().getData();
				List<Map<String, String>> volumes = new ArrayList<Map<String,String>>();
				for (Volume volume : data) {
					String id = volume.getId();
					String name = volume.getName();
					Map<String, String> m = new HashMap<String, String>();
					m.put("volumeId", id);
					m.put("volumeName", name);
					volumes.add(m);
				}
				vo.setVolumes(volumes);
			}
			dataList.add(vo);
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFailData(dataList, "获取容器和卷异常！异常信息："+e.getMessage());
		}
		return Result.buildOkData(dataList, "获取容器和卷成功！");
	}

	public Result<Boolean> isContainerExist(String contanerName) {
		ContainerService containerService = rancher.type(ContainerService.class);
		Map<String, Object> filters = new HashMap<String, Object>();
		filters.put("name", contanerName);
		try {
			Response<TypeCollection<Container>> execute = containerService.list(filters).execute();
			if(execute.isSuccess()) {
				List<Container> data = execute.body().getData();
				if(data != null && data.size() > 0) {
					return Result.buildOkData(true, "容器已经存在！");
				}else {
					return Result.buildOkData(false, "容器不存在！");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFailData(false, "获取容器异常，异常信息："+e.getMessage());
		}
		return Result.buildFailData(false, "获取容器详情失败");
	}
	
	public Result<Boolean> isContainerExistById(String contanerId) {
		ContainerService containerService = rancher.type(ContainerService.class);
		try {
			Response<Container> execute = containerService.get(contanerId).execute();
			if(execute.isSuccess()) {
				Container data = execute.body();
				if(data != null) {
					return Result.buildOkData(true, "容器已经存在！");
				}else {
					return Result.buildOkData(false, "容器不存在！");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFailData(false, "获取容器异常，异常信息："+e.getMessage());
		}
		return Result.buildFailData(false, "获取容器详情失败");
	}
	
	public Result<List<Container>> listAllUserContainers(Map<String, Object> filters){
		ContainerService containerService = rancher.type(ContainerService.class);
		try {
			Response<TypeCollection<Container>> execute = containerService.list(filters).execute();
			if(execute.isSuccess()) {
				List<Container> res = new ArrayList<Container>();
				List<Container> data = execute.body().getData();
				for (int i = 0; i < data.size(); i++) {
					Container container = data.get(i);
					String imageUuid = container.getImageUuid();
					if(!imageUuid.startsWith("docker:rancher") && !imageUuid.contains("sonatype/nexus3")
							&& !imageUuid.contains("novnc-proxy")) {
						logger.info("镜像名称："+imageUuid+",数组索引："+i+",列表长度："+data.size());
						res.add(container);
					}
				}
				return Result.buildOkData(res, "获取用户容器成功");
			}
		} catch (IOException e) {
			e.printStackTrace();
			return Result.buildFail("获取用户容器异常，异常信息："+e.getMessage());
		}
		return Result.buildFail("获取用户容器失败");
	}
}
